﻿
using ERP.Workflow.Designer.Domain;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;

namespace ERP.Workflow.Designer.EntityFrameworkCore;

public static class WorkflowDesignerDbContextModelBuilderExtensions
{
    //TODO: Instead of getting parameters, get a action of SettingManagementModelBuilderConfigurationOptions like other modules
    public static void ConfigureWorkflowDesigner(
        [NotNull] this ModelBuilder builder)
    {
        Check.NotNull(builder, nameof(builder));

        if (builder.IsTenantOnlyDatabase())
        {
            return;
        }


        builder.Entity<Definition>(b => 
        {
            b.ToTable(WorkflowDesignerDbProperties.DbTablePrefix + nameof(Definition));
            b.HasKey(b => b.Id);
            b.Property(x => x.Name).HasMaxLength(100);
            b.Property(x => x.Version).HasMaxLength(100);
            b.HasMany<Node>(m => m.Nodes).WithOne(m=>m.Definition).HasForeignKey(m=>m.DefinitionId);

            b.HasMany<Link>(m => m.Links).WithOne(m => m.Definition).HasForeignKey(m => m.DefinitionId); ;
            b.ConfigureByConvention();
            b.ApplyObjectExtensionMappings();

            b.HasQueryFilter(m=>!m.IsDeleted);
        });

        builder.Entity<Node>(b =>
        {
            b.ToTable(WorkflowDesignerDbProperties.DbTablePrefix + nameof(Node));
            b.HasKey(b => b.Id);
            b.Property(x => x.Height);
            b.Property(x => x.Width);
            b.Property(x => x.X);
            b.Property(x => x.Y);
            b.Property(x => x.TenantId);
            b.Property(x => x.Title);


            b.HasOne<Definition>(m => m.Definition).WithMany(m=>m.Nodes).HasForeignKey(m=>m.DefinitionId);
            b.HasMany<Port>(m => m.Ports).WithOne(m=>m.Parent).HasForeignKey(m=>m.ParentId);
            b.HasMany<Link>(m => m.Links).WithOne(m => m.SourceNode).HasForeignKey(m => m.SourceNodeId);
            b.ConfigureByConvention();
            b.ApplyObjectExtensionMappings();
            b.HasQueryFilter(m => !m.IsDeleted);
        });
        builder.Entity<Port>(b =>
        {
            b.ToTable(WorkflowDesignerDbProperties.DbTablePrefix + nameof(Port));
            b.HasKey(b => b.Id);
            b.Property(x => x.Height);
            b.Property(x => x.Width);
            b.Property(x => x.X);
            b.Property(x => x.Y);


            b.HasOne<Node>(m => m.Parent).WithMany(m => m.Ports).HasForeignKey(m => m.ParentId);
            // b.HasMany<Link>(m => m.Links).WithOne(m => m.SourcePort).HasForeignKey(m => m.SourcePortId);

            b.HasOne<Definition>(m => m.Definition);
            b.ConfigureByConvention();
            b.ApplyObjectExtensionMappings();
            b.HasQueryFilter(m => !m.IsDeleted);
        });

        builder.Entity<Link>(b =>
        {
            b.ToTable(WorkflowDesignerDbProperties.DbTablePrefix + nameof(Link));
            b.HasKey(b => b.Id);
            b.Property(x => x.Width);
            b.Property(x => x.Color).HasMaxLength(10); ;
            b.Property(x => x.SourceNodeId);
            b.Property(x => x.TargetNodeId);
            b.Property(x => x.SourcePortId);
            b.Property(x => x.TargetPortId);
            b.Property(x => x.SourceLinkMarkerPath).HasMaxLength(100); ;
            b.Property(x => x.SourceLinkMarkerWidth);
            b.Property(x => x.TargetLinkMarkerPath).HasMaxLength(100); ;
            b.Property(x => x.TargetLinkMarkerWidth);


            b.HasOne<Port>(m => m.SourcePort);
            b.HasOne<Port>(m => m.TargetPort);
            b.HasOne<Node>(m => m.SourceNode);
            b.HasOne<Node>(m => m.TargetNode);
            b.HasOne<Definition>(m => m.Definition);


            b.HasMany<LinkVertex>(m=>m.Vertices).WithOne(m=>m.Parent).HasForeignKey(m=>m.ParentId);
            b.HasMany<LinkLabel>(m=>m.Labels).WithOne(m=>m.Parent).HasForeignKey(m=>m.ParentId);
            b.ConfigureByConvention();
            b.ApplyObjectExtensionMappings();
            b.HasQueryFilter(m => !m.IsDeleted);
        });
        builder.Entity<LinkVertex>(b =>
        {
            b.ToTable(WorkflowDesignerDbProperties.DbTablePrefix + nameof(LinkVertex));
            b.HasKey(b => b.Id);
            b.Property(b => b.X);
            b.Property(b => b.Y);
            b.Property(b => b.TenantId);
            b.HasOne<Link>(m => m.Parent).WithMany(m=>m.Vertices).HasForeignKey(m=>m.ParentId);
            b.HasOne<Definition>(m => m.Definition);
            b.ConfigureByConvention();
            b.ApplyObjectExtensionMappings();
            b.HasQueryFilter(m => !m.IsDeleted);
        });

        builder.Entity<LinkLabel>(b =>
        {
            b.ToTable(WorkflowDesignerDbProperties.DbTablePrefix + nameof(LinkLabel));
            b.HasKey(b => b.Id);
            b.Property(b => b.TenantId);
            b.HasOne<Link>(m => m.Parent).WithMany(m => m.Labels).HasForeignKey(m => m.ParentId);


            b.HasOne<Definition>(m=>m.Definition);
            b.ConfigureByConvention();
            b.ApplyObjectExtensionMappings();
            b.HasQueryFilter(m => !m.IsDeleted);
        });




      

        builder.TryConfigureObjectExtensions<WorkflowDesignerDbContext>();
    }
}
